//++++++++++++++++++++++++++++++++++++++++
//Fighting for great,share generate value!
//Build the best soft by golang,let's go!
//++++++++++++++++++++++++++++++++++++++++
//Author:ShirDon <http://www.shirdon.com>
//Email:hcbsts@163.com;  823923263@qq.com
//++++++++++++++++++++++++++++++++++++++++
package main

import (
	"flag"
	"fmt"
	"gitee.com/shirdonl/captchas_with_go"
	"gitee.com/shirdonl/configs_with_go"
	"html"
	"image/png"
	"log"
	"net/http"
	"os"
)

var (
	ccaptcha   *captchas_with_go.Captcha
	configFile = flag.String("c", "examples/config.conf", "the config file")
)

const (
	DEFAULT_PORT = "80"
	DEFAULT_LOG  = "./captcha-server.log"
)

func main() {

	flag.Parse()

	port := DEFAULT_PORT

	if _, err := os.Stat(*configFile); os.IsNotExist(err) {
		log.Fatalf("config file:%s not exists!", *configFile)
		os.Exit(1)
	}

	c, err := config.ReadDefault(*configFile)
	if nil != err {
		port = DEFAULT_PORT
	}
	port, err = c.String("service", "port")
	if nil != err {
		port = DEFAULT_PORT
	}

	captcha, err := captchas_with_go.CreateCaptchaFromConfigFile(*configFile)

	if nil != err {
		log.Fatalf("config load failed:%s", err.Error())
	} else {
		ccaptcha = captcha
	}

	//绑定控制器
	http.HandleFunc("/showimage", ShowImageHandler)
	http.HandleFunc("/getkey", GetKeyHandler)
	http.HandleFunc("/verify", VerifyHandler)
	http.HandleFunc("/", DefaultHandler)

	//运行服务
	s := &http.Server{Addr: ":" + port}

	log.Printf("=======server is runing=======")
	log.Fatal(s.ListenAndServe())
}

func ShowImageHandler(w http.ResponseWriter, r *http.Request) {
	key := r.FormValue("key")
	if len(key) >= 0 {
		cimg, err := ccaptcha.GetImage(key)
		log.Println("err", err)
		if nil == err {
			w.Header().Add("Content-Type", "image/png")
			png.Encode(w, cimg)
		} else {
			log.Printf("show image error:%s", err.Error())
			w.WriteHeader(500)
		}
	}

	log.Printf("[cmd:showimage][remote_addr:%s][key:%s]", r.RemoteAddr, key)
}

//获取key处理器
func GetKeyHandler(w http.ResponseWriter, r *http.Request) {
	callback := html.EscapeString(r.FormValue("callback"))

	key, err := ccaptcha.GetKey(4)
	retStr := "{error_no:%d,error_msg:'%s',key:'%s'}"

	errorNo := 0
	errorMsg := ""

	if nil != err {
		errorNo = 1
		errorMsg = err.Error()
	}

	if callback != "" {
		retStr = "%s(" + retStr + ")"
		retStr = fmt.Sprintf(retStr, callback, errorNo, errorMsg, key)
	} else {
		retStr = fmt.Sprintf(retStr, errorNo, errorMsg, key)
	}
	w.Header().Add("Content-Type", "application/json")
	w.Write([]byte(retStr))

	log.Printf("[cmd:getkey][remote_addr:%s][key:%s]", r.RemoteAddr, key)
}

//验证处理器
func VerifyHandler(w http.ResponseWriter, r *http.Request) {
	key := r.FormValue("key")
	code := r.FormValue("code")
	callback := html.EscapeString(r.FormValue("callback"))

	retStr := "{error_no:%d,error_msg:'%s',key:'%s'}"
	errorNo := 0
	errorMsg := ""

	suc, msg := ccaptcha.Verify(key, code)

	if false == suc {
		errorNo = 1
		errorMsg = msg
	}

	if callback != "" {
		retStr = "%s(" + retStr + ")"
		retStr = fmt.Sprintf(retStr, callback, errorNo, errorMsg, key)
	} else {
		retStr = fmt.Sprintf(retStr, errorNo, errorMsg, key)
	}
	w.Header().Add("Content-Type", "application/json")
	w.Write([]byte(retStr))
	log.Printf("[cmd:verify][remote_addr:%s][key:%s][code:%s]", r.RemoteAddr, key, code)
}

//默认处理器
func DefaultHandler(w http.ResponseWriter, r *http.Request) {
	retstr := "<html>"
	retstr += "<body>"
	retstr += "<h1>captchas_with_go</h1>"
	retstr += "<h2>document</h2>"
	retstr += "<p>see:<a href='https://gitee.com/shirdonl/captchas_with_go.git'>https://gitee.com/shirdonl/captchas_with_go.git</a></p>"
	retstr += "<h2>interface</h2>"
	retstr += "<p><a href='/getkey'>/getkey</a></p>"
	retstr += "<p><a href='/showimage'>/showimage</a></p>"
	retstr += "<p><a href='/verify'>/verify</a></p>"
	retstr += "</body>"
	retstr += "</html>"
	w.Write([]byte(retstr))
}
